import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @file StreamSocket.java
 * 
 * @version 0.1
 * @author Chris Sewell 10008342
 */
public class StreamSocket {

	Socket socket;
	OutputStream streamOut;
	OutputStreamWriter streamWriter;
	DataOutputStream dataOut;
	PrintWriter socketOut;
	InputStream streamIn;
	InputStreamReader streamReader;
	DataInputStream dataIn;
	BufferedReader socketIn;
	boolean status;

	public StreamSocket(Socket socket) throws IOException {
		this.socket = socket;
		// Create all socket objects for file and string transmition
		streamOut = socket.getOutputStream();
		streamWriter = new OutputStreamWriter(streamOut);
		dataOut = new DataOutputStream(streamOut);
		socketOut = new PrintWriter(streamWriter);

		streamIn = socket.getInputStream();
		streamReader = new InputStreamReader(streamIn);
		dataIn = new DataInputStream(streamIn);
		socketIn = new BufferedReader(streamReader);

		status = true;
	}

	/**
	 * These abstractions hide the try catch statements and flushes required for
	 * sending/receiving data
	 */
	public void sendString(String message) {// Send and flush a string
		socketOut.println(message);
		socketOut.flush();
	}

	public String recieveString() {// Receive a string
		try {
			return socketIn.readLine();
		} catch (IOException ex) {
			Logger.getLogger(StreamSocket.class.getName()).log(Level.SEVERE,
					null, ex);
		}
		return null;
	}

	public void sendBytes(byte[] data, int length) {// Send and flush a byte
													// array
		try {
			dataOut.write(data, 0, length);
			dataOut.flush();
		} catch (IOException ex) {
			Logger.getLogger(StreamSocket.class.getName()).log(Level.SEVERE,
					null, ex);
		}
	}

	public byte[] recieveBytes(int length) {// Receive a byte array
		byte[] temp = new byte[length];
		try {
			dataIn.read(temp, 0, length);
		} catch (IOException ex) {
			Logger.getLogger(StreamSocket.class.getName()).log(Level.SEVERE,
					null, ex);
		}
		return temp;
	}

	public String displayDetail() {// Returns client socket info for server
									// console output
		InetAddress clientAddress;
		clientAddress = socket.getInetAddress();// Hostname will not show in
												// Windows 7 UWE
		return clientAddress.getHostName() + " "
				+ clientAddress.getHostAddress();
	}

	public void kill() throws IOException {// Close all socket objects
		status = false;
		socket.close();
		streamOut.close();
		dataOut.close();
		streamWriter.close();
		socketOut.close();
		streamIn.close();
		dataIn.close();
		streamReader.close();
		socketIn.close();
	}

	public boolean isOpen() {
		return status;
	}

	public char readChar() throws IOException
	{
			return (char)dataIn.readByte();
	}
}
